package com.g4m.baselib.swagger;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;


/**
 * haosenwei[haosenwei@hudesen.com]
 * created at 5/14/20 11:26
 * <p>Copyright 2008-2019 snsndk.com</p>
 */
@Configuration
@EnableWebMvc
@EnableSwagger2
public class SwaggerConfig {

    public static final String SPLIT = ";";

    /**
     * 创建doc
     *
     * @param title       标题
     * @param version     版本
     * @param packageName 包路径
     * @param groupName   分组名称
     * @return doc
     */
    public static Docket createDocket(String title, String version, String packageName, String groupName) {
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo(title, version))
                .select()
                .apis(basePackage(packageName))
                .paths(PathSelectors.any())
                .build();
        if (StringUtils.isNotBlank(groupName)) {
            docket = docket.groupName(groupName);
        }
        return docket;
    }

    /**
     * 创建doc
     *
     * @param title       标题
     * @param version     版本
     * @param packageName 包路径
     * @return doc
     */
    public static Docket createDocket(String title, String version, String packageName) {
        return createDocket(title, version, packageName, null);
    }

    /**
     * 设置api
     *
     * @param title   标题
     * @param version 版本
     * @return apiinfo
     */
    private static ApiInfo apiInfo(String title, String version) {
        return new ApiInfoBuilder()
                .title(title)//文档说明
                .version(version)//文档版本说明
                .build();
    }

    /**
     * 重写basePackage方法，使能够实现多包访问，复制贴上去
     *
     * @param basePackage 包路径
     * @return Predicate
     */
    public static Predicate<RequestHandler> basePackage(String basePackage) {
        return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
    }

    /**
     * 重写包
     *
     * @param basePackage 包路径
     * @return function
     */
    private static Function<Class<?>, Boolean> handlerPackage(String basePackage) {
        return input -> {
            // 循环判断匹配
            for (String strPackage : basePackage.split(SPLIT)) {
                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
                    return true;
                }
            }
            return false;
        };
    }

    /**
     * 重写包
     *
     * @param input 输入
     * @return class
     */
    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
        return Optional.fromNullable(input.declaringClass());
    }
}
